using System;
using Geometry;
using Gltf;

namespace Cesium3DTilesSelection
{
    public class RasterOverlayTile : IDisposable
    {
        public enum LoadState
        {
            /**
             * @brief Indicator for a placeholder tile.
             */
            Placeholder = -2,

            /**
             * @brief The image request or image creation failed.
             */
            Failed = -1,

            /**
             * @brief The initial state
             */
            Unloaded = 0,

            /**
             * @brief The request for loading the image data is still pending.
             */
            Loading = 1,

            /**
             * @brief The image data has been loaded and the image has been created.
             */
            Loaded = 2,

            /**
             * @brief The rendering resources for the image data have been created.
             */
            Done = 3
        };

        /**
         * @brief Tile availability states.
         *
         * Values of this enumeration are returned by
         * {@link RasterOverlayTile::update}, which in turn is called by
         * {@link Tile::update}. These values are used to determine whether a leaf
         * tile has been reached, but the associated raster tiles are not yet the
         * most detailed ones that are available.
         */
        public enum MoreDetailAvailable
        {

            /** @brief There are no more detailed raster tiles. */
            No = 0,

            /** @brief There are more detailed raster tiles. */
            Yes = 1,

            /** @brief It is not known whether more detailed raster tiles are available.
             */
            Unknown = 2
        };
        public RasterOverlay pOverlay { get; set; }
        public double TargetGeometricError { get; set; }
        public Rectangle Rectangle { get; set; }
        public LoadState State { get; set; }
        public ImageCesium Image { get; set; }
        public object pRendererResources { get; set; }
        public int References { get; set; }
        public MoreDetailAvailable moreDetailAvailable { get; set; }
        public static implicit operator bool(RasterOverlayTile self)
        {
            return self == null ? false : true;
        }
        public RasterOverlayTile(RasterOverlay overlay)
        {
            this.pOverlay = overlay;
            this.TargetGeometricError = 0.0;
            this.Rectangle = new Rectangle(0, 0, 0, 0);
            this.State = LoadState.Placeholder;
            this.Image = null;
            this.pRendererResources = null;
            this.References = 0;
            this.moreDetailAvailable = MoreDetailAvailable.Unknown;

        }
        public RasterOverlayTile(RasterOverlay overlay, double targetGeometricError, Rectangle rectangle)
        {
            this.pOverlay = overlay;
            this.TargetGeometricError = targetGeometricError;
            this.Rectangle = rectangle;
            this.State = LoadState.Unloaded;
            this.Image = null;
            this.pRendererResources = null;
            this.References = 0;
            this.moreDetailAvailable = MoreDetailAvailable.Unknown;
        }
        public void Dispose()
        {
            UnityEngine.Debug.Log("移除 栅格tile");
        }
        internal void addReference()
        {
            ++this.References;
        }

        internal void loadInMainThread()
        {
            if (this.State != RasterOverlayTile.LoadState.Loaded)
            {
                return;
            }

            // Do the final main thread raster loading
            RasterOverlayTileProvider pTileProvider = this.pOverlay.getTileProvider();
            this.pRendererResources = pTileProvider.pPrepareRendererResources.prepareRasterInMainThread(this, pRendererResources);

            this.State = LoadState.Done;
        }

        internal void releaseReference()
        {
            UnityEngine.Debug.Assert(this.References > 0);
            int references = --this.References;
            if (references == 0)
            {
                UnityEngine.Debug.Assert(this.pOverlay);
                UnityEngine.Debug.Assert(this.pOverlay.getTileProvider());
                this.pOverlay.getTileProvider().removeTile(this);
            }
        }
    }
}